package com.aaron.client;


import com.google.gwt.user.client.ui.Composite;
import net.sf.jwc.gwt.user.client.ui.HtmlTextArea;

import com.google.gwt.user.client.Window;




/**
 * @author aaron
 * 
 * Binds Document, HtmlTextArea, TinyMCE editor into a Composite widget
 * 
 * {@linkplain 
 * http://google-code-prettify.googlecode.com/svn/trunk/README.html}
 * 
 * {@linkplain 
 *	http://zamov.online.fr/EXHTML/DHTML/DHTML_983246.html}
 */

public class SyntaxColoredTextArea extends Composite {

	
	final Document document;
	HtmlTextArea textarea;
	String tinymce_editor_id;
	static int id=-1;

	/**
	 * 
	 * @param document The document that will be accessed by the TinyMCE editor
	 */
	public SyntaxColoredTextArea(final Document document) {
		this.document=document;
		id++;
		tinymce_editor_id="mce_editor_"+id+"";
		textarea = new HtmlTextArea();
		textarea.setText(document.getText());
		initWidget(textarea);
		
		updateSyntaxHighlighting();
	}
	/**
	 * Copies the contents of the TinyMCE editor to the document model
	 *
	 */
	public void syncToDocument(){
		document.setText(getCleanedText());
		//Window.alert("syncToDocument:\n"+document.getText());
	}
	/**
	 * 
	 * @return The updated document reflecting any changes made by the TinyMCE editor
	 */
	public Document getDocument(){
		return document;
	}
	/**
	 * Refreshes the syntax highlighting in the TinyMCE editor
	 *
	 */
	public native void updateSyntaxHighlighting()/*-{
		if(this.@com.aaron.client.SyntaxColoredTextArea::tinymce_editor_id!=null){
			var editor_id=this.@com.aaron.client.SyntaxColoredTextArea::tinymce_editor_id;
			$wnd.tinyMCE.execInstanceCommand(editor_id,"mceSyntaxHighlight", false, null);
		}
	}-*/;
	/**
	 * 
	 * @return true:The document has been changed
	 */
	public native boolean isDirty()/*-{
		var editor_id=this.@com.aaron.client.SyntaxColoredTextArea::tinymce_editor_id;
		return $wnd.tinyMCE.getInstanceById(editor_id).isDirty();
	}-*/;
	/**
	 * Sets the dirty flag to false
	 *
	 */
	public native void setNotDirty()/*-{
		var editor_id=this.@com.aaron.client.SyntaxColoredTextArea::tinymce_editor_id;
		$wnd.tinyMCE.getInstanceById(editor_id).triggerSave(false, false);
	}-*/;
	/**
	 * 
	 * @return The string of text in the TinyMCE editor without syntax highlighting/formatting html
	 */
	private native String getCleanedText()/*-{
		if(this.@com.aaron.client.SyntaxColoredTextArea::tinymce_editor_id!=null){
			var editor_id=this.@com.aaron.client.SyntaxColoredTextArea::tinymce_editor_id;
			var s=$wnd.tinyMCE.getInstanceById(editor_id).getBody().innerHTML;
			//strip spans
			s=s.replace(/(<span([^>]+)>)/ig,"");
		    s=s.replace(/(<\/span>)/ig,"");
		    
			s=s.replace(/(<pre([^>]*)>)/ig,"");
		    s=s.replace(/(<\/pre>)/ig,"");
		    s=s.replace(/(<br \/>)/ig,"\n");
		    s=s.replace(/(<br>)/ig,"\n");
			//replace html entities
			s=s.replace(/&lt;/ig,"<");
			s=s.replace(/&gt;/ig,">");
			s=s.replace(/&nbsp;/g," ");
			s=s.replace(/&amp;/g,"&");
			return s;
		}
	}-*/;
	private native String getCleanedText2()/*-{
	if(this.@com.aaron.client.SyntaxColoredTextArea::tinymce_editor_id!=null){
		var editor_id=this.@com.aaron.client.SyntaxColoredTextArea::tinymce_editor_id;
		var inst=$wnd.tinyMCE.getInstanceById(editor_id);
		inst.triggerSave();
		var s=this.@com.aaron.client.SyntaxColoredTextArea::textarea.getText()();
		return s;
	}
}-*/;
	/**
	 * 
	 * @param s string containing no html entities
	 * @return string with characters converted to html entities
	 */
	private native String addEntities(String s)/*-{
		s=s.replace(/&/ig,"&amp;");
		s=s.replace(/</ig,"&lt;");
		s=s.replace(/>/ig,"&gt;");
		return s;
	}-*/;
	
	

}
